package com.flex.mobile.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.stereotype.Service;

import com.flex.mobile.dao.IGenericDAO;
import com.flex.mobile.dao.model.TaxiTimer;

@Service("timerDao")
public class TimerDao implements IGenericDAO<TaxiTimer> {
   private final SimpleJdbcTemplate template;

   private final SimpleJdbcInsert insertContact;
   
   @Autowired
   public TimerDao(DataSource dataSource) {
      this.template = new SimpleJdbcTemplate(dataSource);
      this.insertContact = new SimpleJdbcInsert(dataSource).withTableName("Timer").usingGeneratedKeyColumns("ID");
   }

   private final RowMapper<TaxiTimer> summaryRowMapper = new ParameterizedRowMapper<TaxiTimer>() {
      @Override
      public TaxiTimer mapRow(ResultSet rs, int rowNum) throws SQLException {
         TaxiTimer timer = new TaxiTimer();
         timer.setTimerID(rs.getLong("id"));
         timer.setTimerName(rs.getString("name"));
         timer.setTimerType(rs.getString("type"));
         timer.setTimerKind(rs.getString("kind"));
         timer.setObjectID(rs.getString("objectID"));
         timer.setCurrentState(rs.getString("currentState"));
         timer.setRegisteTime(rs.getLong("registeTime"));
         timer.setRegTimeDesc(rs.getString("regTimeDesc"));
         timer.setFirstTriggeTime(rs.getLong("firstTriggeTime"));
         timer.setCycleTimes(rs.getLong("cycleTimes"));
         timer.setNextTriggeTime(rs.getLong("nextTriggeTime"));
         timer.setLeftCycleTimes(rs.getLong("leftCycleTimes"));
         timer.setCycleInterval(rs.getLong("cycleInterval"));
         timer.setTrigTimeDesc(rs.getString("trigTimeDesc"));
         return timer;
      }
   };
   
   private final RowMapper<TaxiTimer> keyRowMapper = new ParameterizedRowMapper<TaxiTimer>() {
      @Override
      public TaxiTimer mapRow(ResultSet rs, int rowNum) throws SQLException {
         TaxiTimer timer = new TaxiTimer();
         timer.setTimerID(rs.getLong("id"));
         timer.setFirstTriggeTime(rs.getLong("firstTriggeTime"));
         return timer;
      }
   };

   @Override
   public List<TaxiTimer> findAll() {
      return null;
   }

   @Override
   public List<TaxiTimer> findByName(String name) {
      return null;
   }

   @Override
   public TaxiTimer findById(long id) {
      String sql = "select * from timer where id = ? ";

      return this.template.queryForObject(sql, this.summaryRowMapper, id);
   }

   @Override
   public TaxiTimer create(TaxiTimer item) {
      Map<String, Object> parameters = new HashMap<String, Object>();
      parameters.put("name", item.getTimerName());
      parameters.put("type", item.getTimerType());
      parameters.put("kind", item.getTimerKind());
      parameters.put("currentState", item.getCurrentState());
      parameters.put("objectID", item.getObjectID());
      
      parameters.put("registeTime", item.getRegisteTime());
      parameters.put("regTimeDesc", item.getRegTimeDesc());
      parameters.put("firstTriggeTime", item.getFirstTriggeTime());
      parameters.put("cycleTimes", item.getCycleTimes());
      
      parameters.put("nextTriggeTime", item.getNextTriggeTime());
      parameters.put("leftCycleTimes", item.getLeftCycleTimes());
      parameters.put("cycleInterval", item.getCycleInterval());
      parameters.put("trigTimeDesc", item.getTrigTimeDesc());
      Number id = this.insertContact.executeAndReturnKey(parameters);
      item.setTimerID(id.intValue());
      return item;
   }

   @Override
   public boolean update(TaxiTimer item) {
      StringBuffer sql = new StringBuffer();
      sql.append("UPDATE timer SET name=?, type=?, kind=?, currentState=?, registeTime=?, regTimeDesc=?, firstTriggeTime=?, cycleTimes=?, cycleInterval=?, trigTimeDesc=? ");
      sql.append(" WHERE id=?");
      int count = this.template.update(sql.toString(), item.getTimerName(), item.getTimerType(), item.getTimerKind(), item.getCurrentState(), item.getRegisteTime(),
            item.getRegTimeDesc(), item.getFirstTriggeTime(), item.getCycleTimes(), item.getCycleInterval(), item.getTrigTimeDesc(), item.getTimerID());
      return count == 1;
   }

   @Override
   public boolean remove(TaxiTimer item) {
      int count = this.template.update("DELETE FROM timer WHERE id=?", item.getTimerID());
      return count == 1;
   }
   
   public List<TaxiTimer> loadOnceTimer(long firstTriggeTime) {
      String sql = "SELECT id,firstTriggeTime FROM Timer WHERE type=? AND firstTriggeTime<=? AND currentState=? ORDER BY firstTriggeTime ASC";
      return this.template.query(sql, keyRowMapper, TaxiTimer.TYPE_ONCE, firstTriggeTime, TaxiTimer.STAT_ACTIVE);
   }
   
   public List<TaxiTimer> findTimerByObjectId(String timerKind, String objectID) {
      String sql = "SELECT * FROM Timer WHERE kind=? AND objectID=? AND currentState=? ORDER BY firstTriggeTime ASC";
      return this.template.query(sql, keyRowMapper, timerKind, objectID, TaxiTimer.STAT_ACTIVE);
   }
   
   public void deleteEndedTimer() {
      this.template.update("DELETE FROM timer WHERE currentState=?", TaxiTimer.STAT_ENDED);
   }
}
